

`ifdef SIM
module sim_tb ();
    //iverilog -DSIM -f sim.txt && vvp a.out
    reg clk = 0;
    reg rst_n = 0;
    reg memory_clk = 0;
    wire clk50m = clk;

    always clk = #10 ~clk;
    always memory_clk = #1.25 ~memory_clk;
    always rst_n = #100 1;
    always #140000 $finish;
    reg[31:0] counter = 0;

    reg[31:0] apb_addr = 0;
    reg[31:0] apb_hwdata = 0;
    reg[3:0]  sdio_dat_test = 'hf;
    reg[31:0] sdio_clk_cnt = 0;
    wire sdio_clk;

    reg apb_hwrite = 0;
    reg apb_htran = 0;
    wire apb_hsel = apb_htran;
    wire apb_hready;
    reg sdio_cmd_test = 1;

    localparam test_counter = 10;

`define counter_cmp(cnt) (counter==test_counter+cnt||counter==test_counter+cnt+1)
`define counter_cmp_range(cnt1,cnt2)        ((counter>=cnt1) && (counter<=cnt2))
//`define TEST_WRITE

    reg need_rsp = 0;
    reg long_rsp = 0;
    reg dat_en = 0;
    reg dat_wr = 0;
    reg[15:0] data_len;
    reg send_dat_wr = 0;
    reg[31:0] send_dat = 0;
    reg[5:0]  cmd = 0;
    reg       cmd_en = 0;
    reg[31:0] argu = 0;
    reg       sdio_clk_nt = 0;
    inout     cmd_d;
    pullup(cmd_d);
    reg       cmd_i = 1'bz;
    reg       cmd_oe = 0;
    assign cmd_d = cmd_i;

    inout[3:0] dat_d;
    pullup(dat_d[0]);
    pullup(dat_d[1]);
    pullup(dat_d[2]);
    pullup(dat_d[3]);
    reg[3:0]   dat_i = 4'hz;
    //assign dat_d  = dat_i;
    reg recv_dat_en = 1;
    reg recv_stream_ready = 0;
    reg dat_next_en = 0;
    reg send_stream_valid = 0;
    wire send_stream_ready;

    always @(posedge clk) begin
        counter <= counter + 1;
        sdio_clk_nt <= sdio_clk;

        if(sdio_clk && !sdio_clk_nt)
            sdio_clk_cnt <= sdio_clk_cnt + 1;

        if(send_stream_ready)begin
            //send_stream_valid <= 0;
        end
        if(`counter_cmp(20))begin
            cmd_en <= 1;
            need_rsp <= 1;
            dat_en   <= 1;
            cmd      <= ~0;
            argu     <= 1;
            long_rsp <= 0;
            dat_wr   <= 1;
        end
        else if(`counter_cmp(340))begin
            dat_i <= 0;
            send_stream_valid <= 1;
        end
        else if(`counter_cmp(400))begin
            send_stream_valid <= 1;
        end
        else if(`counter_cmp(170))begin
            cmd_i <= 0;
        end
        else if(`counter_cmp(400))begin
            //recv_dat_en <= 0;
            //recv_stream_ready <= 1;
        end
        else if(`counter_cmp(460))begin
            //recv_stream_ready <= 1;
        end
        else if(`counter_cmp(460))begin
            recv_dat_en <= 1;
        end
        else if(`counter_cmp(600))begin
            dat_next_en <= 1;
        end
        else if(`counter_cmp(500))begin
            dat_en  <= 0;
        end
        else if(`counter_cmp_range(700,800))begin
            //测试多块数据
            if(`counter_cmp(700))begin
                dat_i <= 0;
            end
            else
                dat_i <= 'hz;
        end
        else begin
            //send_stream_valid   <= 0;
            cmd_i  <= 1'bz;
            dat_i  <= 'hz;
            recv_stream_ready <= 1;
        end
    end

    sdio u_sdio(
        .io_sdio_clk            (sdio_clk),
        .io_sdio_cmd            (cmd_d),
        .io_sdio_dat            (dat_d),
        .io_sdio_cmd_en         (cmd_en),
        .io_sdio_cmd_valu       (cmd),
        .io_sdio_cmd_argu       (argu),
        .io_sdio_cmd_need_rsp   (need_rsp),
        .io_sdio_cmd_long_rsp   (long_rsp),
        .io_sdio_rsp            (),
        .io_sdio_bus_4bit       (1'b1),
        .io_sdio_clkdiv         ('d0),
        .io_sdio_dat_en         (dat_en),
        .io_sdio_dat_write      (dat_wr),
        .io_sdio_data_len       (data_len),
        .io_sdio_send_dat       (send_dat),
        .io_sdio_send_dat_wr    (send_dat_wr),
        .io_sdio_recv_dat       (),
        .io_sdio_recv_dat_wr    (),

        .io_timeout_reset       (~rst_n),
        .io_timeout_tick        (100000000),
        .io_recv_stream_ready   (recv_stream_ready),
        .io_block_size          (8),

        .io_send_stream_valid   (send_stream_valid),
        .io_send_stream_ready   (send_stream_ready),
        .io_send_stream_payload ('hffffffff),

        .io_dat_next_en         (dat_next_en),

        .io_sdio_recv_dat_en    (recv_dat_en),
        .clk(clk),
        .reset(!rst_n)
    );

    initial begin
        $dumpfile("test.vcd");
        $dumpvars(0, sim_tb);
    end
endmodule
`endif
